/*
 *
 *  * Copyright (c) 2024 Huawei Technologies Co., Ltd.
 *  * openFuyao is licensed under Mulan PSL v2.
 *  * You can use this software according to the terms and conditions of the Mulan PSL v2.
 *  * You may obtain a copy of Mulan PSL v2 at:
 *  *          http://license.coscl.org.cn/MulanPSL2
 *  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 *  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 *  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 *  * See the Mulan PSL v2 for more details.
 *
 */

// Package controller
package controller

import (
	"context"
	"fmt"
	"os"
	"os/exec"
	"strings"
	"time"

	"gopkg.in/yaml.v2"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/client-go/util/retry"
	ctrl "sigs.k8s.io/controller-runtime"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/controller"

	"volcano-config-service/pkg/zlog"
)

// NodeConfigController 结构体定义
type NodeConfigController struct {
	client.Client
	Scheme *runtime.Scheme
}

// ConfigRequest 定义了发送给 agent 的配置请求结构
type ConfigRequest struct {
	EnableStaticCPUManager bool   `json:"enableStaticCPUManager"`
	EnableNUMADistance     bool   `json:"enableNUMADistance"`
	KubeletConfigPath      string `json:"kubeletConfigPath,omitempty"`
}

// KubeletConfig 定义了要修改的k8s配置内容
type KubeletConfig struct {
	Kind                         string            `yaml:"kind"`
	ApiVersion                   string            `yaml:"apiVersion"`
	CpuManagerPolicy             string            `yaml:"cpuManagerPolicy"`
	FeatureGates                 map[string]bool   `yaml:"featureGates"`
	TopologyManagerPolicyOptions map[string]string `yaml:"topologyManagerPolicyOptions"`
	KubeReserved                 map[string]string `yaml:"kubeReserved"`
	SystemReserved               map[string]string `yaml:"systemReserved"`
}

const (
	// RequeueTimeMinutes 定义了重新入队的时间间隔（分钟）
	RequeueTimeMinutes = 5
)

// SetupWithManager 设置 controller 与 manager
func (r *NodeConfigController) SetupWithManager(mgr ctrl.Manager) error {
	// 设置控制器监听 NodeConfig 资源
	return ctrl.NewControllerManagedBy(mgr).
		For(&NodeConfig{}).
		WithOptions(controller.Options{
			MaxConcurrentReconciles: 1,
		}).
		Complete(r)
}

// Reconcile 处理NodeConfig资源的调谐
func (r *NodeConfigController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
	// 获取当前节点名称
	nodeName := os.Getenv("NODE_NAME")
	if nodeName == "" {
		return ctrl.Result{}, fmt.Errorf("NODE_NAME environment variable not set")
	}

	// 获取 NodeConfig 资源
	nodeConfig := &NodeConfig{}
	if err := r.Get(ctx, req.NamespacedName, nodeConfig); err != nil {
		zlog.FormatInfo("get nodeConfig")
		if !errors.IsNotFound(err) {
			return ctrl.Result{}, err
		}
		return ctrl.Result{Requeue: true}, nil
	}

	// 查找当前节点的配置
	nodeConf := r.findNodeConfiguration(nodeConfig, nodeName)

	// 如果找不到当前节点的配置，添加新的配置
	if nodeConf == nil {
		return r.handleMissingNodeConfig(ctx, nodeConfig, nodeName)
	}

	// 检查并处理配置更新
	return r.handleNodeConfigUpdate(ctx, nodeConfig, nodeName, nodeConf)
}

// findNodeConfiguration 在NodeConfig中查找特定节点的配置
func (r *NodeConfigController) findNodeConfiguration(nodeConfig *NodeConfig, nodeName string) *NodeConfiguration {
	for _, nc := range nodeConfig.Spec.Nodes {
		if nc.NodeName == nodeName {
			return &nc
		}
	}
	return nil
}

// handleMissingNodeConfig 处理节点配置不存在的情况
func (r *NodeConfigController) handleMissingNodeConfig(ctx context.Context,
	nodeConfig *NodeConfig, nodeName string) (ctrl.Result, error) {

	currentConfig, err := r.readKubeletConfig(KubeletConfigPath)
	if err != nil {
		zlog.Error(err, "Failed to read kubelet config")
		return ctrl.Result{}, err
	}

	// 解析当前配置
	currentStaticCPUEnabled, currentNUMAEnabled := r.parseCurrentConfiguration(currentConfig)

	// 添加新的节点配置
	nodeConfig.Spec.Nodes = append(nodeConfig.Spec.Nodes, NodeConfiguration{
		NodeName:               nodeName,
		EnableStaticCPUManager: currentStaticCPUEnabled,
		EnableNUMADistance:     currentNUMAEnabled,
		KubeletConfigPath:      KubeletConfigPath,
	})

	if err := r.Update(ctx, nodeConfig); err != nil {
		zlog.Error(err, "Failed to update NodeConfig")
		return ctrl.Result{}, err
	}

	return ctrl.Result{Requeue: true}, nil
}

// handleNodeConfigUpdate 处理节点配置更新
func (r *NodeConfigController) handleNodeConfigUpdate(ctx context.Context,
	nodeConfig *NodeConfig, nodeName string, nodeConf *NodeConfiguration) (ctrl.Result, error) {

	// 读取当前配置
	currentConfig, err := r.readKubeletConfig(KubeletConfigPath)
	if err != nil {
		zlog.Error(err, "Failed to read kubelet config")
		return ctrl.Result{}, err
	}

	// 解析当前配置
	currentStaticCPUEnabled, currentNUMAEnabled := r.parseCurrentConfiguration(currentConfig)

	// 检查是否需要更新配置
	if nodeConf.EnableStaticCPUManager != currentStaticCPUEnabled ||
		nodeConf.EnableNUMADistance != currentNUMAEnabled {

		return r.updateConfiguration(ctx, nodeConfig, nodeName, nodeConf, currentConfig)
	}

	return ctrl.Result{RequeueAfter: time.Minute * RequeueTimeMinutes}, nil
}

// parseCurrentConfiguration 解析kubelet配置中的策略设置
func (r *NodeConfigController) parseCurrentConfiguration(
	currentConfig map[string]interface{}) (bool, bool) {

	// 解析CPU管理策略
	cpuManagerPolicy, ok := currentConfig["cpuManagerPolicy"]
	currentStaticCPUEnabled := false
	if ok {
		policyStr, isString := cpuManagerPolicy.(string)
		currentStaticCPUEnabled = isString && policyStr == "static"
	}

	// 解析NUMA距离策略
	currentNUMAEnabled := false
	if topologyOptsRaw, exists := currentConfig["topologyManagerPolicyOptions"]; exists {
		currentNUMAEnabled = r.parseNUMADistanceOption(topologyOptsRaw)
	}

	return currentStaticCPUEnabled, currentNUMAEnabled
}

// parseNUMADistanceOption 解析NUMA距离配置选项
func (r *NodeConfigController) parseNUMADistanceOption(topologyOptsRaw interface{}) bool {
	switch opts := topologyOptsRaw.(type) {
	case map[interface{}]interface{}:
		if numaValue, ok := opts["prefer-closest-numa-nodes"]; ok {
			return r.parseNUMABoolValue(numaValue)
		}
	case map[string]interface{}:
		if numaValue, ok := opts["prefer-closest-numa-nodes"]; ok {
			return r.parseNUMABoolValue(numaValue)
		}
	default:
		return false
	}
	return false
}

// parseNUMABoolValue 解析NUMA布尔值配置
func (r *NodeConfigController) parseNUMABoolValue(value interface{}) bool {
	switch v := value.(type) {
	case string:
		return strings.EqualFold(v, "true")
	case bool:
		return v
	default:
		return false
	}
}

// updateConfiguration 执行配置更新流程
func (r *NodeConfigController) updateConfiguration(ctx context.Context,
	nodeConfig *NodeConfig, nodeName string, nodeConf *NodeConfiguration,
	currentConfig map[string]interface{}) (ctrl.Result, error) {

	// 更新状态为配置中
	if err := r.updateNodeStatusWithRetry(ctx, nodeConfig, nodeName,
		NodeConfigStateConfiguring, ""); err != nil {
		zlog.Error(err, "Failed to update node status")
		return ctrl.Result{}, err
	}

	// 更新配置
	if err := r.updateKubeletConfig(currentConfig, nodeConf); err != nil {
		zlog.Error(err, "Failed to update kubelet config")
		if updateErr := r.updateNodeStatusWithRetry(ctx, nodeConfig, nodeName,
			NodeConfigStateFailed, err.Error()); updateErr != nil {
			zlog.Error(updateErr, "Failed to update failure status")
		}
		return ctrl.Result{}, err
	}

	// 更新成功状态
	if err := r.updateNodeStatusWithRetry(ctx, nodeConfig, nodeName,
		NodeConfigStateConfigured, ""); err != nil {
		zlog.Error(err, "Failed to update success status")
		return ctrl.Result{}, err
	}

	return ctrl.Result{RequeueAfter: time.Minute * RequeueTimeMinutes}, nil
}

func (r *NodeConfigController) readKubeletConfig(path string) (map[string]interface{}, error) {
	data, err := os.ReadFile(path)
	if err != nil {
		return nil, fmt.Errorf("failed to read kubelet config file: %v", err)
	}

	config := make(map[string]interface{})
	if err := yaml.Unmarshal(data, &config); err != nil {
		return nil, fmt.Errorf("failed to unmarshal kubelet config: %v", err)
	}

	return config, nil
}

// updateKubeletConfig 更新kubelet配置
func (r *NodeConfigController) updateKubeletConfig(config map[string]interface{}, nodeConf *NodeConfiguration) error {
	// 跟踪配置是否被修改
	modified := false

	// 获取当前CPU管理策略
	currentPolicy, _ := config["cpuManagerPolicy"].(string)

	// 更新CPU管理策略和NUMA距离设置
	modifiedCPU := r.updateCPUManagerPolicy(config, nodeConf, currentPolicy)
	modifiedNUMA := r.updateNUMADistanceSettings(config, nodeConf, currentPolicy)
	modified = modifiedCPU || modifiedNUMA

	// 确保基本配置字段存在
	r.ensureBasicConfigFields(config)

	// 如果配置有修改，应用更改
	if modified {
		return r.applyConfigChanges(nodeConf, config)
	}

	return nil
}

// updateCPUManagerPolicy 更新CPU管理策略
func (r *NodeConfigController) updateCPUManagerPolicy(
	config map[string]interface{}, nodeConf *NodeConfiguration, currentPolicy string) bool {
	if config == nil {
		return false
	}

	modified := false

	// 启用静态CPU管理
	if nodeConf.EnableStaticCPUManager && currentPolicy != "static" {
		config["cpuManagerPolicy"] = "static"
		r.ensureResourceReservations(config)
		modified = true
	} else if !nodeConf.EnableStaticCPUManager && currentPolicy == "static" {
		// 禁用静态CPU管理
		config["cpuManagerPolicy"] = "none"
		modified = true
	} else {
		return modified
	}

	return modified
}

// ensureResourceReservations 确保资源预留配置存在
func (r *NodeConfigController) ensureResourceReservations(config map[string]interface{}) bool {
	if config == nil {
		return false
	}

	modified := false

	// 检查并添加系统预留资源配置
	if _, ok := config["systemReserved"].(map[string]interface{}); !ok {
		config["systemReserved"] = map[string]interface{}{
			"cpu": "0.5",
		}
		modified = true
	}

	// 检查并添加kube预留资源配置
	if _, ok := config["kubeReserved"].(map[string]interface{}); !ok {
		config["kubeReserved"] = map[string]interface{}{
			"cpu": "0.5",
		}
		modified = true
	}

	return modified
}

// updateNUMADistanceSettings 更新NUMA距离设置
func (r *NodeConfigController) updateNUMADistanceSettings(
	config map[string]interface{}, nodeConf *NodeConfiguration, currentPolicy string) bool {

	modified := false

	if nodeConf.EnableNUMADistance {
		modified = r.enableNUMADistance(config, currentPolicy)
	} else {
		modified = r.disableNUMADistance(config)
	}

	return modified
}

// enableNUMADistance 启用NUMA距离功能
func (r *NodeConfigController) enableNUMADistance(config map[string]interface{}, currentPolicy string) bool {
	if config == nil {
		return false
	}

	modified := false

	// 设置CPU Manager为static
	if currentPolicy != "static" {
		config["cpuManagerPolicy"] = "static"
		r.ensureResourceReservations(config)
		modified = true
	}

	// 更新特性门控
	modifiedFeatures := r.updateFeatureGates(config)

	// 更新拓扑管理器策略选项
	modifiedTopology := r.updateTopologyOptions(config, true)

	return modified || modifiedFeatures || modifiedTopology
}

// disableNUMADistance 禁用NUMA距离功能
func (r *NodeConfigController) disableNUMADistance(config map[string]interface{}) bool {
	modified := false

	if topologyOptsRaw, exists := config["topologyManagerPolicyOptions"]; exists {
		switch topologyOpts := topologyOptsRaw.(type) {
		case map[interface{}]interface{}:
			if _, exists := topologyOpts["prefer-closest-numa-nodes"]; exists {
				topologyOpts["prefer-closest-numa-nodes"] = "false"
				modified = true
			}
		case map[string]interface{}:
			if _, exists := topologyOpts["prefer-closest-numa-nodes"]; exists {
				topologyOpts["prefer-closest-numa-nodes"] = "false"
				modified = true
			}
		default:
			return modified
		}
	}

	return modified
}

// updateFeatureGates 更新特性门控设置
func (r *NodeConfigController) updateFeatureGates(config map[string]interface{}) bool {
	if config == nil {
		return false
	}

	featureGates, ok := config["featureGates"].(map[string]interface{})
	if !ok {
		featureGates = make(map[string]interface{})
		config["featureGates"] = featureGates
	}

	featureGates["TopologyManagerPolicyOptions"] = true
	featureGates["TopologyManagerPolicyBetaOptions"] = true
	featureGates["TopologyManagerPolicyAlphaOptions"] = true

	return true
}

// updateTopologyOptions 更新拓扑管理器选项
func (r *NodeConfigController) updateTopologyOptions(config map[string]interface{}, enableNUMA bool) bool {
	if config == nil {
		return false
	}

	topologyOpts, ok := config["topologyManagerPolicyOptions"].(map[string]interface{})
	if !ok {
		topologyOpts = make(map[string]interface{})
		config["topologyManagerPolicyOptions"] = topologyOpts
	}

	currentNUMAValue, _ := topologyOpts["prefer-closest-numa-nodes"].(string)
	numaValue := "true"
	if !enableNUMA {
		numaValue = "false"
	}

	if currentNUMAValue != numaValue {
		topologyOpts["prefer-closest-numa-nodes"] = numaValue
		return true
	}

	return false
}

// ensureBasicConfigFields 确保基本配置字段存在
func (r *NodeConfigController) ensureBasicConfigFields(config map[string]interface{}) {
	// 首先检查config是否为nil
	if config == nil {
		return
	}

	if _, ok := config["kind"].(string); !ok {
		config["kind"] = "KubeletConfiguration"
	}

	if _, ok := config["apiVersion"].(string); !ok {
		config["apiVersion"] = "kubelet.config.k8s.io/v1beta1"
	}
}

// applyConfigChanges 应用配置更改：删除状态文件、保存配置并重启kubelet
func (r *NodeConfigController) applyConfigChanges(nodeConf *NodeConfiguration, config map[string]interface{}) error {
	// 删除 cpu_manager_state 文件
	if err := r.deleteCPUManagerStateFile(); err != nil {
		return fmt.Errorf("failed to delete cpu_manager_state file: %v", err)
	}

	// 保存kubelet配置
	if err := r.saveKubeletConfig(nodeConf.KubeletConfigPath, config); err != nil {
		return fmt.Errorf("failed to save kubelet config: %v", err)
	}

	// 重启kubelet服务
	if KubeletConfigPath == "/var/lib/kubelet/config.yaml" {
		if err := r.restartKubelet(); err != nil {
			return fmt.Errorf("failed to restart kubelet: %v", err)
		}
	} else {
		if err := r.restartBkeKubelet(); err != nil {
			return fmt.Errorf("failed to restart kubelet: %v", err)
		}
	}

	return nil
}

// 添加删除 cpu_manager_state 文件的方法
func (r *NodeConfigController) deleteCPUManagerStateFile() error {
	//  cpu_manager_state 文件的路径为 /var/lib/kubelet/cpu_manager_state
	statePath := "/var/lib/kubelet/cpu_manager_state"
	if err := os.Remove(statePath); err != nil && !os.IsNotExist(err) {
		return err
	}
	return nil
}

func (r *NodeConfigController) saveKubeletConfig(path string, config map[string]interface{}) error {
	data, err := yaml.Marshal(config)
	if err != nil {
		return fmt.Errorf("failed to marshal kubelet config: %v", err)
	}

	// 创建临时文件
	const FilePermission = 0644
	tmpfile := path + ".tmp"
	if err := os.WriteFile(tmpfile, data, FilePermission); err != nil {
		return fmt.Errorf("failed to write temporary config file: %v", err)
	}

	// 重命名临时文件到目标文件
	if err := os.Rename(tmpfile, path); err != nil {
		// 清理临时文件
		if err := os.Remove(tmpfile); err != nil {
			return fmt.Errorf("failed to remove temporary file: %v", err)
		}
		return fmt.Errorf("failed to replace config file: %v", err)
	}

	return nil
}

func (r *NodeConfigController) restartKubelet() error {
	// 使用 systemctl 重启 kubelet
	cmd := exec.Command("nsenter",
		"-i/mnt/proc/1/ns/ipc",
		"-m/mnt/proc/1/ns/mnt",
		"-n/mnt/proc/1/ns/net",
		"systemctl", "restart", "kubelet")
	return cmd.Run()
}

func (r *NodeConfigController) restartBkeKubelet() error {
	// 使用 systemctl 重启 kubelet
	cmd := exec.Command("nsenter",
		"-i/mnt/proc/1/ns/ipc",
		"-m/mnt/proc/1/ns/mnt",
		"-n/mnt/proc/1/ns/net",
		"nerdctl", "-n", "k8s.io", "restart", "kubelet")
	return cmd.Run()
}

// updateNodeStatusWithRetry 使用重试机制更新节点状态
func (r *NodeConfigController) updateNodeStatusWithRetry(ctx context.Context,
	nodeConfig *NodeConfig, nodeName, state, errMsg string) error {

	return retry.RetryOnConflict(retry.DefaultRetry, func() error {
		// 重新获取最新的资源以避免冲突
		latest := &NodeConfig{}
		if err := r.Get(ctx, client.ObjectKey{
			Namespace: nodeConfig.Namespace,
			Name:      nodeConfig.Name,
		}, latest); err != nil {
			return err
		}

		// 更新状态
		updated := false
		for i, status := range latest.Status.NodeStatuses {
			if status.NodeName == nodeName {
				latest.Status.NodeStatuses[i].State = state
				latest.Status.NodeStatuses[i].Error = errMsg
				latest.Status.NodeStatuses[i].LastUpdateTime = metav1.Now()
				if state == NodeConfigStateConfigured {
					latest.Status.NodeStatuses[i].StaticCPUManagerEnabled =
						nodeConfig.Spec.Nodes[i].EnableStaticCPUManager
					latest.Status.NodeStatuses[i].NUMADistanceEnabled =
						nodeConfig.Spec.Nodes[i].EnableNUMADistance
				}
				updated = true
				break
			}
		}

		// 如果没有找到现有状态，添加新的
		if !updated {
			newStatus := NodeStatus{
				NodeName:       nodeName,
				State:          state,
				Error:          errMsg,
				LastUpdateTime: metav1.Now(),
			}
			latest.Status.NodeStatuses = append(latest.Status.NodeStatuses, newStatus)
		}

		// 更新最后更新时间
		latest.Status.LastUpdateTime = metav1.Now()

		// 更新资源
		return r.Status().Update(ctx, latest)
	})
}

// InitializeNodeConfig 初始化 NodeConfig CR 或将当前节点添加到现有 CR 中
func InitializeNodeConfig(client client.Client) error {
	ctx := context.Background()

	// 获取当前节点名称
	nodeName, err := getNodeName()
	if err != nil {
		return err
	}

	// 尝试获取 NodeConfig 资源
	nodeConfig := &NodeConfig{}
	zlog.FormatInfo("正在检查 nodeConfig 是否存在")

	err = client.Get(ctx, types.NamespacedName{Name: "kubelet-config", Namespace: "default"}, nodeConfig)
	if err == nil {
		zlog.FormatInfo("nodeConfig 已存在，检查是否需要添加当前节点")

		// 检查当前节点是否已在配置中
		nodeFound := false
		for _, nc := range nodeConfig.Spec.Nodes {
			if nc.NodeName == nodeName {
				nodeFound = true
				zlog.FormatInfo("节点 %s 已存在于 NodeConfig 中", nodeName)
				break
			}
		}

		// 如果节点不在配置中，添加它
		if !nodeFound {
			zlog.FormatInfo("正在将节点 %s 添加到现有 NodeConfig 中", nodeName)
			return addNodeToExistingConfig(ctx, client, nodeConfig, nodeName)
		}

		return nil
	}

	if !errors.IsNotFound(err) {
		return err
	}

	// NodeConfig 不存在，创建一个新的
	return createNewNodeConfig(ctx, client, nodeName)
}

// addNodeToExistingConfig 将当前节点添加到现有的 NodeConfig CR 中
func addNodeToExistingConfig(ctx context.Context, client client.Client,
	nodeConfig *NodeConfig, nodeName string) error {

	// 读取当前 kubelet 配置
	currentConfig, err := readCurrentKubeletConfig()
	if err != nil {
		return err
	}

	// 分析当前配置状态
	currentStaticCPUEnabled, currentNUMAEnabled := analyzeCurrentConfig(currentConfig)

	// 创建新的节点配置
	newNodeConf := NodeConfiguration{
		NodeName:               nodeName,
		EnableStaticCPUManager: currentStaticCPUEnabled,
		EnableNUMADistance:     currentNUMAEnabled,
		KubeletConfigPath:      KubeletConfigPath,
	}

	// 将节点添加到配置中
	return retry.RetryOnConflict(retry.DefaultRetry, func() error {
		// 获取最新的 NodeConfig 以避免冲突
		latest := &NodeConfig{}
		err := client.Get(ctx, types.NamespacedName{
			Name:      nodeConfig.Name,
			Namespace: nodeConfig.Namespace,
		}, latest)
		if err != nil {
			return err
		}

		// 添加新的节点配置
		latest.Spec.Nodes = append(latest.Spec.Nodes, newNodeConf)

		// 更新 NodeConfig CR
		if err := client.Update(ctx, latest); err != nil {
			zlog.FormatError("更新 NodeConfig 失败: %v", err)
			return err
		}

		zlog.FormatInfo("成功将节点 %s 添加到 NodeConfig", nodeName)
		return nil
	})
}

// getNodeName 获取当前节点名称
func getNodeName() (string, error) {
	nodeName := os.Getenv("NODE_NAME")
	if nodeName == "" {
		return "", fmt.Errorf("NODE_NAME environment variable not set")
	}
	return nodeName, nil
}

// createNewNodeConfig 创建新的节点配置
func createNewNodeConfig(ctx context.Context, client client.Client, nodeName string) error {
	// 读取当前kubelet配置
	currentConfig, err := readCurrentKubeletConfig()
	if err != nil {
		return err
	}

	// 分析当前配置状态
	currentStaticCPUEnabled, currentNUMAEnabled := analyzeCurrentConfig(currentConfig)

	// 创建并保存新的NodeConfig CR
	return createNodeConfigCR(ctx, client, nodeName, currentStaticCPUEnabled, currentNUMAEnabled)
}

// readCurrentKubeletConfig 读取当前kubelet配置
func readCurrentKubeletConfig() (map[string]interface{}, error) {
	zlog.FormatInfo("reading current kubelet config")
	currentConfig := make(map[string]interface{})

	data, err := os.ReadFile(KubeletConfigPath)
	if err != nil {
		zlog.FormatError("Failed to read kubelet config: %v", err)
		return nil, fmt.Errorf("failed to read kubelet config: %v", err)
	}

	if err := yaml.Unmarshal(data, &currentConfig); err != nil {
		zlog.FormatError("Failed to unmarshal kubelet config: %v", err)
		return nil, fmt.Errorf("failed to unmarshal kubelet config: %v", err)
	}

	return currentConfig, nil
}

// analyzeCurrentConfig 分析当前配置状态
func analyzeCurrentConfig(currentConfig map[string]interface{}) (bool, bool) {
	// 检查CPU管理器策略
	cpuManagerPolicy, ok := currentConfig["cpuManagerPolicy"].(string)
	currentStaticCPUEnabled := ok && cpuManagerPolicy == "static"

	// 检查NUMA距离设置
	var currentNUMAEnabled bool
	if topologyOpts, ok := currentConfig["topologyManagerPolicyOptions"].(map[string]interface{}); ok {
		numaValue, exists := topologyOpts["prefer-closest-numa-nodes"]
		currentNUMAEnabled = exists && numaValue == "true"
	}

	return currentStaticCPUEnabled, currentNUMAEnabled
}

// createNodeConfigCR 创建NodeConfig自定义资源
func createNodeConfigCR(ctx context.Context, client client.Client,
	nodeName string, staticCPUEnabled, numaEnabled bool) error {

	zlog.FormatInfo("creating new nodeConfig CR")
	nodeConfig := &NodeConfig{
		ObjectMeta: metav1.ObjectMeta{
			Name:      "kubelet-config",
			Namespace: "default",
		},
		Spec: NodeConfigSpec{
			Nodes: []NodeConfiguration{
				{
					NodeName:               nodeName,
					EnableStaticCPUManager: staticCPUEnabled,
					EnableNUMADistance:     numaEnabled,
					KubeletConfigPath:      KubeletConfigPath,
				},
			},
		},
	}

	if err := client.Create(ctx, nodeConfig); err != nil {
		zlog.FormatError("Failed to create NodeConfig: %v", err)
		return fmt.Errorf("failed to create NodeConfig: %v", err)
	}

	zlog.FormatInfo("successfully created nodeConfig CR")
	return nil
}
